#include "si4432.h"

static struct bflb_device_s *gpio;
xQueueHandle rf_queue;
extern xQueueHandle sound_queue;

uint8_t get_ver()
{
    return RF4432_ReadReg(DEVICE_VERSION);
}

void RF4432_ReInit(){
    RF4432_SDN_1;
    bflb_mtimer_delay_ms(1500);
    RF4432_Init();
    uint8_t ver = get_ver();
    LOG_E("ver: 0x%02x \r\n", ver);
}

void si4432_task(void *arg)
{
    GPIO_Init();
    rf_queue = xQueueCreate(1, 32);
    char *queue_buff = NULL;
    RF4432_Init();
    uint8_t ver = get_ver();
    LOG_E("ver: 0x%02x \r\n", ver);
    LOG_E("发送端 \r\n");

    while (1) {
        queue_buff = pvPortMalloc(1024);
        memset(queue_buff, 0, 1024);
        if (xQueueReceive(rf_queue, queue_buff, portMAX_DELAY) == pdTRUE) {
            printf("queue_buff: ");
            int len = 0;
            for (int i = 0; i < 1024; i++) {
                printf("0x%02x ", queue_buff[i]);
                len++;
                if (queue_buff[i] == 0xFF) {
                    if ((i + 1) < 1024 && queue_buff[i + 1] == 0x00) {
                        break;
                    }
                }
            }
            printf("\r\n");
            if (queue_buff[0] == 0xAA) {
                // RF4432_TxRxBuf[3] = queue_buff[2];
                RF4432_TxPacket_Send(queue_buff, len);
            }
        }
        vPortFree(queue_buff);
    }
}

//-------------------------------------------------------SPI单字节读取函数--------------------------------------------------------
uint8_t SPI_Read(void)
{
    uint8_t i, rxdata;
    rxdata = 0x00;
    for (i = 0; i < 8; i++) {
        rxdata = rxdata << 1;
        RF4432_SCLK_1;
        //RF4432_SDO_1;
        //P1DIR &= ~BIT3;
        if (RF4432_SDO_IN) //读取最高位，保存至最末尾，通过左移位完成整个字节
        {
            LOG_D("SPI_Read RF4432_SDO_IN 1\r\n");
            rxdata |= 0x01;
        } else {
            LOG_D("SPI_Read RF4432_SDO_IN 0\r\n");
            rxdata &= ~0x01;
        }
        //P1DIR |= BIT3;
        bflb_mtimer_delay_us(20);
        RF4432_SCLK_0;
        bflb_mtimer_delay_us(20);
    }
    LOG_D("SPI_Read rxdata: 0x%02x\r\n", rxdata);
    return rxdata;
}
//---------------------------------------------------------SPI单字节写入函数----------------------------------------------
void SPI_Write(uint8_t txdata)
{
    LOG_D("SPI_Write txdata: 0x%02x\r\n", txdata);
    uint8_t i;
    for (i = 0; i < 8; i++) {
        if (txdata & 0x80) //总是发送最高位
        {
            LOG_D("SPI_Write RF4432_SDI_1\r\n");
            RF4432_SDI_1;
        } else {
            LOG_D("SPI_Write RF4432_SDI_0\r\n");
            RF4432_SDI_0;
        }
        RF4432_SCLK_1;
        bflb_mtimer_delay_us(20);
        txdata = txdata << 1;
        RF4432_SCLK_0;
    }
}
//---------------------------------------------------------RF4432寄存器读取函数-----------------------------------------------------------
uint8_t RF4432_ReadReg(uint8_t addr)
{
    LOG_D("RF4432_ReadReg addr: 0x%02x\r\n", addr);
    uint8_t value;
    RF4432_SEL_0;
    SPI_Write(addr | RR);
    value = SPI_Read();
    RF4432_SEL_1;
    return value;
}
//---------------------------------------------------------RF4432寄存器写入函数----------------------------------------------------------
void RF4432_WriteReg(uint8_t addr, uint8_t value)
{
    LOG_D("RF4432_WriteReg addr: 0x%02x,value : 0x%02x\r\n", addr, value);
    RF4432_SEL_0;
    SPI_Write(addr | WR);
    SPI_Write(value);
    RF4432_SEL_1;
}
//---------------------------------------------------------RF4432寄存器写入函数-----------------------------------------------------------
void RF4432_WriteBurestReg(uint8_t addr, uint8_t *p, uint8_t count)
{
    uint8_t i;
    RF4432_SEL_0;
    SPI_Write(addr | WR);
    LOG_E("RF4432_WriteBurestReg addr:0x%02X data:", addr);
    for (i = 0; i < count; i++) {
        SPI_Write(p[i]);
        printf("0x%02X ", p[i]);
    }
    printf("\r\n");
    RF4432_SEL_1;
}
//---------------------------------------------------------RF4432寄存器读取函数------------------------------------------------------------
void RF4432_ReadBurestReg(uint8_t addr, uint8_t *p, uint8_t count)
{
    uint8_t i;
    RF4432_SEL_0;
    SPI_Write(addr | RR);
    for (i = 0; i < count; i++) {
        p[i] = SPI_Read();
    }
    RF4432_SEL_1;
}

/*初始化GPIO*/
void GPIO_Init()
{
    gpio = bflb_device_get_by_name("gpio");
    /* spi cs */
    bflb_gpio_init(gpio, SPI_CS_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
    /* spi clk */
    bflb_gpio_init(gpio, SPI_CLK_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
    /* spi miso */
    bflb_gpio_init(gpio, SPI_MISO_PIN, GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
    /* spi mosi */
    bflb_gpio_init(gpio, SPI_MOSI_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);

    /* nirq */
    bflb_gpio_init(gpio, IRQ_PIN, GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);

    /* sdn */
    bflb_gpio_init(gpio, SDN_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);

    /* 收发模式切换控制端 */
    bflb_gpio_init(gpio, PAC_PIN, GPIO_OUTPUT | GPIO_FLOAT | GPIO_SMT_EN | GPIO_DRV_1);
}

//----------------------------------------------------------RF4432射频芯片初始化函数------------------------------------------------------
void RF4432_Init(void)
{
    RF4432_SDN_0; //允许RF4432工作

    bflb_mtimer_delay_ms(60);

    RF4432_WriteReg(GPIO0_CONFIGURATION, 0xca); //GPIO 0 当做普通输出口
    RF4432_WriteReg(GPIO1_CONFIGURATION, 0xca); //GPIO 1 当做普通输出口
    RF4432_WriteReg(GPIO2_CONFIGURATION, 0xca); //GPIO 2 输出收到的数据

    bflb_mtimer_delay_ms(20);

    RF4432_ReadReg(INTERRUPT_STATUS_1);
    RF4432_ReadReg(INTERRUPT_STATUS_2);

    RF4432_WriteReg(OPERATING_FUNCTION_CONTROL_1, 0x80); //软件复位，详细请见P101页
    bflb_mtimer_delay_ms(40);

    RF4432_ReadReg(INTERRUPT_STATUS_1);
    RF4432_ReadReg(INTERRUPT_STATUS_2);

    RF4432_WriteReg(FREQUENCY_BAND_SELECT, 0x53); //频段选择   		reg75H
    RF4432_WriteReg(NOMINAL_CARRIER_FREQUENCY_1, 0x4B);
    RF4432_WriteReg(NOMINAL_CARRIER_FREQUENCY_0, 0x00);       //标称载波频率（通信频率433MHZ 	reg76H）
    RF4432_WriteReg(TX_DATA_RATE_1, 0x13);                    //发射数据波特率1 TX_DR=10^3*txdr[15:0]/2^16 kbit/s
    RF4432_WriteReg(TX_DATA_RATE_0, 0xA9);                    //发射数据波特率0
    RF4432_WriteReg(MODULATION_MODE_CONTROL_1, 0x2c);         //调制模式控制1
    RF4432_WriteReg(CHARGEPUMP_CURRENT_TRIMMING_OVERRIDE, 0x80);         // 发射不需要 CLK，FiFo ， FSK模式
    RF4432_WriteReg(TX_POWER, 0x07);                          //发射功率
    RF4432_WriteReg(FREQUENCY_DEVIATION, 0x04);               //频率偏差   
    RF4432_WriteReg(MODULATION_MODE_CONTROL_2, 0x22);               //频率偏差   25KHz  f=fd[7:0]*625Hz
    RF4432_WriteReg(IF_FILTER_BANDWIDTH, 0x27);               //IF滤波器带宽      BW = 75.2Khz; Rb = 50Kbps; Fd = 25Khz;
    RF4432_WriteReg(CLOCK_RECOVERY_OVERSAMPLING_RATIO, 0xA1); //时钟恢复过抽样率
    RF4432_WriteReg(CLOCK_RECOVERY_OFFSET_2, 0x20);           //时钟恢复偏差2
    RF4432_WriteReg(CLOCK_RECOVERY_OFFSET_1, 0x4E);           //时钟恢复偏差1
    RF4432_WriteReg(CLOCK_RECOVERY_OFFSET_0, 0xA5);           //时钟恢复偏差0
    RF4432_WriteReg(CLOCK_RECOVERY_TIMING_LOOP_GAIN_1, 0x00); //时钟恢复定时增益1
    RF4432_WriteReg(CLOCK_RECOVERY_TIMING_LOOP_GAIN_0, 0x9F); //时钟恢复定时增益0
    RF4432_WriteReg(AFC_LOOP_GEARSHIFT_OVERRIDE, 0x44);       //使能 afc
    RF4432_WriteReg(AFC_TIMING_CONTROL, 0x0A);       //使能 afc
    RF4432_WriteReg(CLOCK_RECOVERY_GEARSHIFT_OVERRIDE, 0x03);       //使能 afc
    RF4432_WriteReg(AGC_OVERRIDE_1, 0x60);                    //AGC
    RF4432_WriteReg(PREAMBLE_LENGTH, 0x0C);                   //发射16个Nibble的Preamble
    RF4432_WriteReg(PREAMBLE_DETECTION_CONTROL, 0x2a);        //需要检测4个nibble的Preamble
    RF4432_WriteReg(HEADER_CONTROL_2, 0x02);                  //byte 0,1,2,3 是头码，同步字3,2 是同步字
    RF4432_WriteReg(SYNC_WORD_3, 0x2d);                       //同步字为 0x2dd4
    RF4432_WriteReg(SYNC_WORD_2, 0xd4);
    RF4432_WriteReg(DATA_ACCESS_CONTROL, 0x8d); //使能PH+ FIFO模式，高位在前面，使能CRC校验
    RF4432_WriteReg(HEADER_CONTROL_1, 0x00);    //byte0, 1,2,3 作为头码
    RF4432_WriteReg(INTERRUPT_ENABLE_1, 0x03);
    RF4432_WriteReg(INTERRUPT_ENABLE_2, 0x00);

    RF4432_WriteReg(FREQUENCY_HOPPING_CHANNEL_SELECT, 0x0); //不需要跳频
    RF4432_WriteReg(FREQUENCY_HOPPING_STEP_SIZE, 0x0); //不需要跳频
}
//---------------------------------------------------------RF4432设置接收模式函数---------------------------------------------------------------

void RF4432_SetRxMode(void)
{
    RF4432_ReadReg(INTERRUPT_STATUS_1);
    RF4432_ReadReg(INTERRUPT_STATUS_2);
    RF4432_WriteReg(IO_PORT_CONFIGURATION, 0x01);
    RF4432_WriteReg(OPERATING_FUNCTION_CONTROL_1, 0x05); //接收
}
//---------------------------------------------------------RF4432数据包接收函数---------------------------------------------------------------
unsigned char RF4432_RxPacket(void)
{
    //RF4432_IRQ_1;
    //P1DIR &= ~BIT0;
    if (!RF4432_IRQ_IN) {
        LOG_E("RF4432_RxPacket RF4432_IRQ_IN \r\n");
        RF4432_SEL_0;
        uint8_t len = RF4432_ReadReg(RECEIVED_PACKET_LENGTH);
        LOG_E("RF4432_RxPacket len: %d \r\n", len);

        if (len <= RF4432_TxRxBuf_Len) {
            RF4432_ReadBurestReg(FIFO_ACCESS, RF4432_RxRxBuf, len);
            LOG_E("RF4432_ReadBurestReg data:");
            for (int i = 0; i < len; i++) {
                // SPI_Write(RF4432_RxRxBuf[i]);
                printf("0x%02X ", RF4432_RxRxBuf[i]);
            }
            printf("\r\n");
        } else {
            LOG_E("RF4432_RxPacket error receive data len > RF4432_TxRxBuf_Len.  len: %d, RF4432_TxRxBuf_Len:%d \r\n", len, RF4432_TxRxBuf_Len);
            uint8_t *rx = (uint8_t *)malloc(len * sizeof(uint8_t));
            LOG_E("RF4432_ReadBurestReg rx: 0x%02x \r\n", sizeof(rx));
            RF4432_ReadBurestReg(FIFO_ACCESS, rx, len);
            LOG_E("RF4432_ReadBurestReg data:");
            for (int i = 0; i < len; i++) {
                // SPI_Write(RF4432_RxRxBuf[i]);
                printf("0x%02X ", rx[i]);
            }
            printf("\r\n");
            memset(RF4432_RxRxBuf, 0, RF4432_TxRxBuf_Len);
        }
        RF4432_SetRxMode();
        RF4432_SEL_1;
        if (RF4432_RxRxBuf[0] == 0xAA && RF4432_RxRxBuf[2] == RF_DEVICE_ID) {
            return 1;
        }
    }
    return 0;
}
//------------------------------RF4432数据包发送函数----------------------------------------
void RF4432_TxPacket(void)
{
    RF4432_WriteReg(OPERATING_FUNCTION_CONTROL_1, 0x01); //rf模块进入Ready模式
    RF4432_WriteReg(IO_PORT_CONFIGURATION, 0x01);

    RF4432_ReadReg(INTERRUPT_STATUS_1);
    RF4432_ReadReg(INTERRUPT_STATUS_2);

    RF4432_WriteReg(TRANSMIT_PACKET_LENGTH, RF4432_TxRxBuf_Len);

    RF4432_WriteBurestReg(FIFO_ACCESS, RF4432_TxRxBuf, RF4432_TxRxBuf_Len);

    RF4432_WriteReg(INTERRUPT_ENABLE_1, 0x04);
    RF4432_WriteReg(INTERRUPT_ENABLE_2, 0x00);

    RF4432_ReadReg(INTERRUPT_STATUS_1);
    RF4432_ReadReg(INTERRUPT_STATUS_2);

    RF4432_WriteReg(IO_PORT_CONFIGURATION, 0x02);
    RF4432_WriteReg(OPERATING_FUNCTION_CONTROL_1, 0x09); //发射

    while (1) {
        //RF4432_IRQ_1;
        //delay_us(10);
        //P1IN = BIT0;
        //P2DIR &= ~BIT0;
        if (!RF4432_IRQ_IN) {
            LOG_E("RF4432_TxPacket RF4432_IRQ_IN 0 \r\n");
            if (RF4432_ReadReg(INTERRUPT_STATUS_1) & 0x04) //详细请看P95页
            {
                LOG_E("RF4432_TxPacket 0x03 status & 0x04 \r\n");
                break;
            }
        }
        //P2DIR |= BIT0;
    }
}

void RF4432_TxPacket_Send(uint8_t *data, uint16_t size)
{

    RF4432_ReadReg(INTERRUPT_STATUS_1);
    RF4432_ReadReg(INTERRUPT_STATUS_2);

    RF4432_WriteReg(OPERATING_FUNCTION_CONTROL_1, 0x01); //rf模块进入Ready模式
    RF4432_WriteReg(IO_PORT_CONFIGURATION, 0x01);

    RF4432_ReadReg(INTERRUPT_STATUS_1);
    RF4432_ReadReg(INTERRUPT_STATUS_2);

    RF4432_WriteReg(TRANSMIT_PACKET_LENGTH, size);

    RF4432_WriteBurestReg(FIFO_ACCESS, data, size);

    RF4432_WriteReg(INTERRUPT_ENABLE_1, 0x04);
    RF4432_WriteReg(INTERRUPT_ENABLE_2, 0x00);

    RF4432_ReadReg(INTERRUPT_STATUS_1);
    RF4432_ReadReg(INTERRUPT_STATUS_2);

    RF4432_WriteReg(IO_PORT_CONFIGURATION, 0x02);
    RF4432_WriteReg(OPERATING_FUNCTION_CONTROL_1, 0x09); //发射

    while (1) {
        //RF4432_IRQ_1;
        //delay_us(10);
        //P1IN = BIT0;
        //P2DIR &= ~BIT0;
        if (!RF4432_IRQ_IN) {
            LOG_E("RF4432_TxPacket RF4432_IRQ_IN 0 \r\n");
            if (RF4432_ReadReg(INTERRUPT_STATUS_1) & 0x04) //详细请看P95页
            {
                LOG_E("RF4432_TxPacket 0x03 status & 0x04 \r\n");
                break;
            }
        }
        //P2DIR |= BIT0;
    }
}
